package com.etop.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 验证码生成器类，可生成数字、大写、小写字母及三者混合类型的验证码。支持自定义验证码字符数量，支持自定义验证码图片的大小；
 * 支持自定义需排除的特殊字符；支持自定义干扰线的数量，支持自定义验证码图文颜色
 * @author Administrator
 * @version 1.0.1
 */

public class VerifyCode {
    /*
     * 验证码类型：评论
     */
   public static final String VERIFY_TYPE_COMMENT="VERIFY_TYPE_COMMENT";
    /*
     * 验证码类型：仅为数字
     */
   public static final int TYPE_NUM_ONLY=0;
   /*
    * 验证码类型仅为字母，即大写、小写字母混合
    */
   public static final int TYPE_LETTER_ONLY=1;
   /*
    * 验证码类型为数字、大写、小写字母混合
    */
   public static final int TYPE_ALL_MIXED=2;
   /*
    * 验证码类型为数字、大写字母混合
    */
   public static final int TYPE_NUM_UPPER=3;
   /*
    * 验证码类型为数字、小写字母混合
    */
   public static final int TYPE_NUM_LOWER=4;
   /*
    * 验证码类型仅为大写字母
    */
   public static final int TYPE_UPPER_ONLY=5;
   /*
    * 验证码类型仅为小写字母
    */
   public static final int TYPE_LOWER_ONLY=6;
   
   public VerifyCode(){
	   }
   
   /**
    * 生成验证码字符串  //generate:生成
    * @author Administrator
    * @param type  验证码类型，参见本类的静态属性
    * @param length 验证码长度，大于0的整数
    * @param exChars 需要排除的特殊字符（仅对数字、字母混合型有效，无效排除则为null）
    * @return 验证码字符串
    */
 //a-z：97-122  A-Z：65-90  0-9：48-57
   public static String generateTextCode(int type,int length,String exChars){
	   if(length<0)
		   return "";
	   StringBuffer code=new StringBuffer();
	   int i=0;
	   Random r=new Random();
	   switch(type){
	   //紧数字
	   case TYPE_NUM_ONLY:
		   while(i<length){
			   int t=r.nextInt(10);
			   if(exChars==null||exChars.indexOf(t+"")<0){//排除特殊字符；indexOf:没有为-1
				   code.append((char) t);
				   i++;
			   }
		   }
		   break;
		   //仅字母（大写、小写字母混合）
	   case  TYPE_LETTER_ONLY:
		   while(i<length){
			   int t=r.nextInt(123);
			   if((t>=97||(t>65&&t<=90))&&exChars==null||exChars.indexOf((char)t)<0){
				   code.append((char) t);
				   i++;
			   }
		   }
		   break;
		   //数字、大写、小写字母混合
	   case   TYPE_ALL_MIXED:
		   while(i<length){
			   int t=r.nextInt(123);
			   if((t>=97||(t>65&&t<=90)||(t>=48&&t<=57))&&(exChars==null||exChars.indexOf((char)t)<0)){
				   code.append((char) t);
				   i++;
			   }
		   }
		   break;
		   //数字、大写字母
		case TYPE_NUM_UPPER:
			while (i < length) {
				int t = r.nextInt(91);
				if ((t >= 65 || (t >= 48 && t <= 57))
						&& (exChars == null || exChars.indexOf((char) t) < 0)) {
					code.append((char) t);
					i++;
				}
			}
			break;
		   //数字、小写字母混合
		case TYPE_NUM_LOWER:
			while(i<length){
				int t=r.nextInt(123);
				if((t>=97||(t >= 48 && t <= 57))&& (exChars == null || exChars.indexOf((char) t) < 0)){
					code.append((char)t);
					i++;
				}
			}
			break;
			//仅大写字母
		case TYPE_UPPER_ONLY:
			while(i<length){
				int t=r.nextInt(91);
				if((t>=65)&& (exChars == null || exChars.indexOf((char) t) < 0)){
					code.append((char)t);
					i++;
				}
			}
			break;
			//仅小写字母
		case TYPE_LOWER_ONLY:
			while(i<length){
				int t=r.nextInt(123);
				if((t>=97)&& (exChars == null || exChars.indexOf((char) t) < 0)){
					code.append((char)t);
					i++;
				}
			}
	   }
	   return code.toString();
   }
   
   /**
    * 已有验证码，生成验证码图片
    * @param textCode 文本验证码
    * @param width  图片宽度
    * @param height 图片高度
    * @param interLine 图片中干扰线的条数
    * @param randomLocation 每个字符的高低位置是否随机
    * @param backColor 图片颜色，若为null，则采用随机颜色
    * @param foreColor 字体颜色，若为null，则采用随机颜色
    * @param lineColor 干扰线颜色，若为null，则采用随机颜色
    * @return 图片缓存对象
    */
   public static BufferedImage generateImageCode(String textCode,int width,
		   int height,int interLine,boolean randomLocation,Color backColor,
		   Color foreColor,Color lineColor){
	   BufferedImage bi=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
	   Graphics g=bi.getGraphics();
	   //画背景图
	   g.setColor(backColor==null?getRandomColor():backColor);
	   g.fillRect(0, 0, width, height);
	   
	   //画干扰线
	   Random r=new Random();
	   if(interLine>0){
		   int x=0,y=0,x1=width,y1=0;
		   for(int i=0;i<interLine;i++){
			   g.setColor(lineColor==null?getRandomColor():lineColor);
			   y=r.nextInt(height);
			   y1=r.nextInt(height);
			   g.drawLine(x, y, x1, y1);
		   }
	   }
	   //写验证码
	   //字体大小为图片高度的80%
	   int fsize=(int)(height*0.8);
	   int fx=height-fsize;
	   int fy=fsize;
	   g.setFont(new Font("Times New Random",Font.BOLD,20));
	   
	   //写验证码字符
	   for(int i=0;i<textCode.length();i++){
		   fy=randomLocation?(int)((Math.random()*0.3+0.6)*height):fy;//每个字符高低是否随机
		   g.setColor(foreColor==null?getRandomColor():foreColor);
		   g.drawString(textCode.charAt(i)+"", fx, fy);
		   fx+=fsize*0.9;
	   }
	   g.dispose();
	   
	   return bi;
	   
   }
   /**
    * 产生随机颜色
    */
   public static Color getRandomColor(){
	   Random r=new Random();
	   Color c=new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255));
	   return c;
   }
   }
 
   
